package jinyilw.swing.visuals.text;

import javax.swing.text.AbstractDocument;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.Element;
import javax.swing.text.IconView;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;

public class CenterEditorKit extends StyledEditorKit
{
	private static final long serialVersionUID = 8123870678156858905L;

	@Override
	public ViewFactory getViewFactory()
	{
		return new StyledViewFactory();
	}

	static class StyledViewFactory implements ViewFactory
	{
		@Override
		public View create(Element elem)
		{
			String kind = elem.getName();
			if (kind != null)
			{
				if (kind.equals(AbstractDocument.ContentElementName))
					return new WarpLabelView(elem);
				if (kind.equals(AbstractDocument.ParagraphElementName))
					return new ParagraphView(elem);
				if (kind.equals(AbstractDocument.SectionElementName))
					return new CenteredBoxView(elem, View.Y_AXIS);
				if (kind.equals(StyleConstants.ComponentElementName))
					return new ComponentView(elem);
				if (kind.equals(StyleConstants.IconElementName))
					return new IconView(elem);
			}
			return new LabelView(elem);
		}
	}
}

class CenteredBoxView extends BoxView
{
	public CenteredBoxView(Element elem, int axis)
	{
		super(elem, axis);
	}
	@Override
	protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
			int[] spans)
	{
		super.layoutMajorAxis(targetSpan, axis, offsets, spans);
		int textBlockHeight = 0;
		int offset = 0;
		for (int span : spans)
			textBlockHeight += span;

		offset = (targetSpan - textBlockHeight) / 2;
		for (int i = 0; i < offsets.length; i++)
			offsets[i] += offset;
	}
}
class WarpLabelView extends LabelView
{
	public WarpLabelView(Element elem)
	{
		super(elem);
	}

	@Override
	public float getMinimumSpan(int axis)
	{
		switch (axis)
		{
			case View.X_AXIS:
				return 0;
			case View.Y_AXIS:
				if (getResizeWeight(axis) == 0)
					return getPreferredSpan(axis);
				return 0;
			default:
				throw new IllegalArgumentException("Invalid axis: " + axis);
		}
	}
}
